﻿using F29ServerProcess.Interfaces;
using IotContract.Enums;
using IotContract.Models.Jobs;
using IotContract.Models.Jobs.F29;
using IotContract.Models.Process;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;

namespace F29ServerProcess.Services;
/// <summary>
/// 任务服务
/// </summary>
public class ProcessJobService : IProcessJobService
{

    /// <summary>
    /// 入库任务
    /// </summary>
    public ConcurrentDictionary<string, ConcurrentDictionary<string, F29EnterJob>> EnterJobs { get; set; } = new ConcurrentDictionary<string, ConcurrentDictionary<string, F29EnterJob>>();

    /// <summary>
    /// 出库任务
    /// </summary>
    public ConcurrentDictionary<string, ConcurrentDictionary<string, F29OutJob>> OutJobs { get; set; } = new ConcurrentDictionary<string, ConcurrentDictionary<string, F29OutJob>>();
    /// <summary>
    /// 火警任务
    /// </summary>
    public ConcurrentDictionary<string, ConcurrentDictionary<string, F29MoveJob>> FireJobs { get; set; } = new ConcurrentDictionary<string, ConcurrentDictionary<string, F29MoveJob>>();

    /// <summary>
    /// 移库任务
    /// </summary>
    public ConcurrentDictionary<string, ConcurrentDictionary<string, F29MoveJob>> MoveJobs { get; set; } = new ConcurrentDictionary<string, ConcurrentDictionary<string, F29MoveJob>>();

    /// <summary>
    /// 充放电任务
    /// </summary>
    public ConcurrentDictionary<string, F29FmtJob> FmtJobs { get; set; } = new ConcurrentDictionary<string, F29FmtJob>();
    /// <summary>
    /// 移除Job
    /// </summary>
    /// <param name="job"></param>
    /// <param name="type"></param>
    public string RemoveJob(ProcessBaseData job, ProcessProviderType type)
    {
        var matchError = "Job Not Match Type,2:Enter 3:Out 4:Move 5:Fire 6:Fmt";
        switch (type)
        {
            case ProcessProviderType.EnterJob:
                var enterJob = job as F29EnterJob;
                if (enterJob == null) return matchError;
                var quene = EnterJobs.GetValueOrDefault(enterJob.EquipNum);
                if (quene != null)
                {
                    quene.Remove(enterJob.GetKey(), out _);
                }
                break;
            case ProcessProviderType.OutJob:
                var outJob = job as F29OutJob;
                if (outJob == null) return matchError;
                var outQuene = OutJobs.GetValueOrDefault(outJob.EquipNum);
                if (outQuene != null)
                {
                    outQuene.Remove(outJob.GetKey(), out _);
                }
                break;
            case ProcessProviderType.FireJob:
                var fireJob = job as F29OutJob;
                if (fireJob == null) return matchError;
                var fireQuene = FireJobs.GetValueOrDefault(fireJob.EquipNum);
                if (fireQuene != null)
                {
                    fireQuene.Remove(fireJob.GetKey(),out _);
                }
                break;
            case ProcessProviderType.MoveJob:
                var moveJob = job as F29MoveJob;
                if (moveJob == null) return matchError;
                var moveQuene = MoveJobs.GetValueOrDefault(moveJob.EquipNum);
                if (moveQuene != null)
                {
                    moveQuene.Remove(moveJob.GetKey(), out _);
                }
                break;
            case ProcessProviderType.FmtJob:
                var fmtJob = job as F29FmtJob;
                if (fmtJob == null) return matchError;
                var fmtQuene = FmtJobs.GetValueOrDefault(fmtJob.GetKey());
                if (fmtQuene != null)
                {
                    FmtJobs.Remove(fmtJob.GetKey(), out _);
                }
                break;
        }
        return string.Empty;
    }
    /// <summary>
    /// 添加Job
    /// </summary>
    /// <param name="job"></param>
    /// <param name="type"></param>
    public string AddJob(ProcessBaseData job, ProcessProviderType type)
    {
        var matchError = "Job Not Match Type,2:Enter 3:Out 4:Move 5:Fire";
        var existError = "JobId Already Exist";
        var upperError = "Job Sum > 5,Add Stop";
        switch (type)
        {
            case ProcessProviderType.EnterJob:
                var enterJob = job as F29EnterJob;
                if (enterJob == null) return matchError;
                var quene = EnterJobs.GetValueOrDefault(enterJob.EquipNum);

                if (quene == null)
                {
                    quene = new ConcurrentDictionary<string, F29EnterJob>();

                    EnterJobs.TryAdd(enterJob.EquipNum, quene);

                }
                else
                {
                    var exist = quene.ContainsKey(enterJob.GetKey());
                    if (exist) return existError;
                    
                }
               if(quene.Count > 5)
                {
                    return upperError;
                }
                enterJob.CreateTime = DateTime.Now;
                quene.TryAdd(enterJob.GetKey(),enterJob);
                break;
            case ProcessProviderType.OutJob:
                var outJob = job as F29OutJob;
                if (outJob == null) return matchError;
                var outQuene = OutJobs.GetValueOrDefault(outJob.EquipNum);
                if (outQuene == null)
                {
                    outQuene = new ConcurrentDictionary<string, F29OutJob>();
                    OutJobs.TryAdd(outJob.EquipNum, outQuene);
                }
                else
                {
                    var exist = outQuene.ContainsKey(outJob.GetKey());
                    if (exist) return existError;
                }
                if (outQuene.Count > 5)
                {
                    return upperError;
                }
                outJob.CreateTime = DateTime.Now;
                outQuene.TryAdd(outJob.GetKey(), outJob);
                break;
            case ProcessProviderType.FireJob:
                var fireJob = job as F29OutJob;
                if (fireJob == null) return matchError;
                var fireQuene = OutJobs.GetValueOrDefault(fireJob.EquipNum);
                if (fireQuene == null)
                {
                    fireQuene = new ConcurrentDictionary<string, F29OutJob>();
                    OutJobs.TryAdd(fireJob.EquipNum, fireQuene);
                }
                else
                {
                    var exist = fireQuene.ContainsKey(fireJob.GetKey());
                    if (exist) return existError;
                }
                if (fireQuene.Count > 5)
                {
                    return upperError;
                }
                fireJob.CreateTime = DateTime.Now;
                fireQuene.TryAdd(fireJob.GetKey(), fireJob);
                break;
            case ProcessProviderType.FmtJob:
                var fmtJob = job as F29FmtJob;
                if (fmtJob == null) return matchError;
                var fmtQuene = FmtJobs.GetValueOrDefault(fmtJob.GetKey());
                if (fmtQuene == null)
                {
                    fmtJob.CreateTime = DateTime.Now;
                    FmtJobs.TryAdd(fmtJob.GetKey(), fmtJob); 
                }
                else
                {
                   return existError;
                }

            
                break;
            case ProcessProviderType.MoveJob:
                var moveJob = job as F29MoveJob;
                if (moveJob == null) return matchError;
                var moveQuene = MoveJobs.GetValueOrDefault(moveJob.EquipNum);
                if (moveQuene == null)
                {
                    moveQuene = new ConcurrentDictionary<string, F29MoveJob>();
                    MoveJobs.TryAdd(moveJob.EquipNum, moveQuene);
                }
                else
                {
                    var exist = moveQuene.ContainsKey(moveJob.GetKey());
                    if (exist) return existError;
                }
                if (moveQuene.Count > 5)
                {
                    return upperError;
                }
                moveJob.CreateTime = DateTime.Now;
                moveQuene.TryAdd(moveJob.GetKey(), moveJob);
                break;


        }

        return string.Empty;
    }


    /// <summary>
    /// 获取Job
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public List<ProcessBaseData> GetJobs(ProcessProviderType type)
    {
        var jobs = new List<ProcessBaseData>();
        switch (type)
        {
            case ProcessProviderType.EnterJob:
                List<ConcurrentDictionary<string, F29EnterJob>>? enterJobDic_List =  EnterJobs.Values.ToList();
                foreach(var jobDic in enterJobDic_List)
                {
                    foreach(var job in jobDic.Values)
                    {
                        jobs.Add(job);
                    }
                }
                break;
            case ProcessProviderType.OutJob:
                List<ConcurrentDictionary<string, F29OutJob>>? outJobDic_List = OutJobs.Values.ToList();
                foreach (var jobDic in outJobDic_List)
                {
                    foreach (var job in jobDic.Values)
                    {
                        jobs.Add(job);
                    }
                }
                break;
            case ProcessProviderType.FireJob:
                List<ConcurrentDictionary<string, F29MoveJob>>? fireJobDic_List = FireJobs.Values.ToList();
                foreach (var jobDic in fireJobDic_List)
                {
                    foreach (var job in jobDic.Values)
                    {
                        jobs.Add(job);
                    }
                }
                break;
            case ProcessProviderType.MoveJob:
                List<ConcurrentDictionary<string, F29MoveJob>>? moveJobDic_List = MoveJobs.Values.ToList();
                foreach (var jobDic in moveJobDic_List)
                {
                    foreach (var job in jobDic.Values)
                    {
                        jobs.Add(job);
                    }
                }
                break;
            case ProcessProviderType.FmtJob:
                List<F29FmtJob>? fmtJob_List = FmtJobs.Values.ToList();
                foreach (var job in fmtJob_List)
                {
                    jobs.Add(job);
                }
                break;
        }
        return jobs;
    }


    /// <summary>
    /// 移除任务
    /// </summary>
    /// <param name="jobKey"></param>
   public void RemoveJob(string jobKey)
    {
       var jobDic= EnterJobs.Values.FirstOrDefault(x=>x.ContainsKey(jobKey));
        if (jobDic != null)
        {
            var job = jobDic.GetValueOrDefault(jobKey);
            if(job!= null)
            {
                RemoveJob(job, ProcessProviderType.EnterJob);
                return;
            }
            
        }

        var outDic = OutJobs.Values.FirstOrDefault(x => x.ContainsKey(jobKey));
        if (outDic != null)
        {
            var job = outDic.GetValueOrDefault(jobKey);
            if (job != null)
            {
                RemoveJob(job, ProcessProviderType.OutJob);
                return;
            }

        }

        var moveDic = MoveJobs.Values.FirstOrDefault(x => x.ContainsKey(jobKey));
        if (moveDic != null)
        {
            var job = moveDic.GetValueOrDefault(jobKey);
            if (job != null)
            {
                RemoveJob(job, ProcessProviderType.MoveJob);
                return;
            }

        }
    }
}
